<template>
	<view class="ly-map-wrapper">
		<!-- 地图展示 -->
		<view :id="mapId" :config="config" :change:config="LyMap.init" :call="option" :change:call="LyMap.call" class="ly-map" />
		<!-- 中心图标 -->
		<image v-if="showCenterIcon" :src="centerIcon||defCenterIcon" class="ly-center-icon" />
		<!-- 定位图标 -->
		<view v-if="showLocationIcon" class="ly-location-icon" @click="onLocation">
			<image :src="locationIcon" class="icon" />
		</view>
	</view>
</template>
 
<script>
	import centerIcon from '@/static/mapImg/point.png';
	import locationIcon from '@/static/mapImg/dw.png';
	export default {
		// 接口参数
		props: {
			// 地图key
			mapKey: {
				type: String,
				default: ''
			},
			// 经纬度
			lonlat: {
				type: Array,
				default: () => ([111.306610,30.689890]),
			},
			// 缩放
			zoom: {
				type: Number,
				default: 13,
			},
			// 是否显示中心定位图标
			showCenterIcon: {
				type: Boolean,
				default: false,
			},
			// 中心点图标
			centerIcon: {
				type: String,
				default: "",
			},
			// 是否显示用户定位图标
			showLocationIcon: {
				type: Boolean,
				default: false,
			},
			// 点击地图定位按钮
			onLocation: {
				type: Function,
				default: () => {}
			},
			// 地图加载完成回调
			onLoaded: {
				type: Function,
				default: () => {}
			},
			// 地图点击事件
			onTouchstart: {
				type: Function,
				default: () => {}
			},
			// 地图做拽开始
			onStartDrag: {
				type: Function,
				default: () => {}
			},
			// 地图做拽结束
			onEndDrag: {
				type: Function,
				default: () => {}
			},
			// 地图缩放结束
			onZoomEnd: {
				type: Function,
				default: () => {}
			},
			// 测试级别
			zoomMapT: {
				type: Number,
				default: 0
			}
		},
		// 数据定义
		data() {
			return {
				// 地图容器id
				mapId: this.genId(),
				// 调用渲染层
				option: {},
				// 地图配置（传递到render中的数据）
				config: {},
				// 调用渲染层队列
				event: [],
				// 事件处理定时器
				timer: null,
				// 中心图标
				defCenterIcon: centerIcon,
				// 定位图标
				locationIcon: locationIcon,
			}
		},
		// 挂载完成后
		mounted() {
			// 设置渲染数据
			this.config = {
				mapId: this.mapId,
				mapKey: this.mapKey,
				lonlat: this.lonlat,
				zoom: this.zoom,
				// TDT_API,
			};
		},
		// 通用方法
		methods: {
			// 生成唯一ID
			genId() {
				let result = '';
				const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
				const charactersLength = characters.length;
				for (let i = 0; i < 30; i++) {
					result += characters.charAt(Math.floor(Math.random() * charactersLength));
				}
				return Date.now() + result;
			},
			// 调用
			call() {
				if (this.timer) return;
				// 消费事件队列（生产者/消费者机制）
				this.timer = setInterval(() => {
					if (this.event.length) {
						this.option = this.event.shift();
					} else {
						clearInterval(this.timer);
						this.timer = null;
					}
				}, 10);
			},
			// 添加事件队列
			addEvent(name, data) {
				// #ifdef APP
				// tips:由于采用监听option改变来调用方法，
				// 如果连续变化两次option，渲染层只会则监不到最后一次
				// 导致调用丢失，所以采用事件队列形式解决，稍微延时10ms
				// 等待渲染进程监听到option变化，在进行更改option
				// 从性能上，几乎无感可以放心使用
				const option = {
					id: this.genId(),
					name: `_${name}`,
					data
				};
				this.event.push(option);
				this.call();
				// #endif
 
				// #ifndef APP
				this[`_${name}`] && this[`_${name}`](data);
				// #endif
			},
			// 获取当前地图层级
			look() {
				this.addEvent("look");
			},
			// 回调
			getZoomCallback(item) {
				console.log('// 回调', item);
				this.$emit('calolBack', item)
			},
			// 设置
			setOption(option) {
				this.addEvent("setOption", option);
			},
			// 设置位置
			setCenter(lon, lat, zoom) {
				this.addEvent("setCenter", {
					lon,
					lat,
					zoom
				});
			},
			// 设置类型 0矢量地图 1卫星地图
			setType(type) {
				this.addEvent("setType", {
					type
				});
			},
			// 设置标注 marks:[{url, width, height, lon, lat}]
			setMarkers(markers = []) {
				this.addEvent("setMarkers", {
					markers
				});
			},
			// 设置缩放
			setZoom(zoom) {
				this.addEvent("setZoom", {
					zoom
				});
			},
			// 重置地图
			resize() {
				this.addEvent("resize");
			},
			// 地图加载完成
			onMapLoad(data) {
				this.onLoaded && this.onLoaded(data);
			},
			// 点击地图定位按钮
			onMapLocation() {
				this.onLocation && this.onLocation();
			},
			// // 点击地图
			// onTouchstart() {
			// 	this.touchstart && this.touchstart();
			// 	this.touchstart()
			// },
			// 开始拖拽地图
			onMapStartDrag(pos) {
				this.onStartDrag && this.onStartDrag(Number(pos.lon).toFixed(6), Number(pos.lat).toFixed(6));
			},
			// 结束拖拽地图
			onMapEndDrag(pos) {
				this.onEndDrag && this.onEndDrag(Number(pos.lon).toFixed(6), Number(pos.lat).toFixed(6));
			},
			// 结束缩放地图
			onMapZoomEnd(pos) {
				this.onZoomEnd && this.onZoomEnd(Number(pos.lon).toFixed(6), Number(pos.lat).toFixed(6));
			},
		},
	}
</script>
 
<script module="LyMap" lang="renderjs">
	// 天地图接口
	const TDT_API = "https://api.tianditu.gov.cn/api?v=4.0&tk=";
	export default {
		data() {
			return {
				// 初始化配置数据
				_config: {},
				// 地图实例
				_mapInstance: {},
				// 注记
				_markerList: [],
				// 地图事件
				_event: {},
			};
		},
		mounted() {
			// console.log('TDT_API', TDT_API);
		},
		methods: {
			// 初始化
			init(newValue, oldValue, ownerInstance, instance) {
				// 防止重复渲染
				if (!Object.keys(newValue).length) {
					return;
				}
				this._config = newValue;
				// 初始化地图
				if (typeof window.LyMap === 'function') {
					this._createMap();
				} else {
					const script = document.createElement('script');
					script.src = TDT_API + newValue.mapKey;
					script.onload = this._createMap.bind(this);
					document.head.appendChild(script);
				}
			},
			// 通过监听call来调用渲染层方法
			call(newValue, oldValue, ownerInstance, instance) {
				// console.log('renderjs的call方法newValue, oldValue, ownerInstance, instance', newValue, oldValue, ownerInstance, instance);
				if (this[newValue.name] && typeof this[newValue.name] === "function") {
					console.log('this[newValue.name]是个方法', this[newValue.name].name);
					this[newValue.name](newValue.data);
				}
			},
			// 创建地图
			_createMap() {
				// 创建地图实例
				try {
					this._mapInstance = new T.Map(this._config.mapId);
					this._mapInstance.addEventListener('load', () => this.$ownerInstance.callMethod('onMapLoad', this
						._config));
					setTimeout(() => this._mapInstance.centerAndZoom(new T.LngLat(this._config.lonlat[0], this._config
						.lonlat[1]), this._config.zoom), 100);
					this._mapInstance.setMapType(TMAP_HYBRID_MAP)
					this._bindEvent();
				} catch (err) {
					console.error(err);
				}
			},
			// 绑定事件
			_bindEvent() {
				try {
					// 绑定开始移动事件
					this._event = {};
					this._event.dragstart = (type, target) => {
						const center = this._mapInstance.getCenter();
						this.$ownerInstance.callMethod('onMapStartDrag', {
							lon: center.getLng(),
							lat: center.getLat()
						});
					};
					this._mapInstance.addEventListener('dragstart', this._event.dragstart.bind(this));
					// 绑定结束移动事件
					this._event.dragend = (type, target) => {
						const center = this._mapInstance.getCenter();
						this.$ownerInstance.callMethod('onMapEndDrag', {
							lon: center.getLng(),
							lat: center.getLat()
						});
					};
					this._mapInstance.addEventListener('dragend', this._event.dragend.bind(this));
					// 绑定地图缩放事件
					this._event.zoomend = (type, target) => {
						const center = this._mapInstance.getCenter();
						this.$ownerInstance.callMethod('onMapZoomEnd', {
							lon: center.getLng(),
							lat: center.getLat()
						});
					};
					this._mapInstance.addEventListener('zoomend', this._event.zoomend.bind(this));
 
					// 添加其它事件 详见:https://lbs.tianditu.gov.cn/api/js4.0/class.html
				} catch (err) {
					console.error(err);
				}
			},
			// 卸载事件
			_unbindEvent() {
				const eventsKey = Object.keys(this._event);
				eventsKey.forEach(key => this._mapInstance.removeEventListener(key));
				this._event = null;
			},
			// 重置地图尺寸
			_resize() {
				try {
					// checkResize（）通知地图其容器大小已更改。在更改了容器对象的大小后调用此方法，以便地图能够调整自己适合于新的大小。
					this._mapInstance.checkResize && this._mapInstance.checkResize();
				} catch (err) {
					console.error(err);
				}
			},
			// 设置选项
			_setOption(data) {
				if (data.type) {
					this._setType(data);
				}
				if (data.center) {
					this._setCenter({
						...data.center,
						zoom: data.zoom
					});
				}
				if (data.markers) {
					this._setMarkers(data);
				}
			},
			// 设置中心点
			_setCenter(data) {
				try {
					this._resize(); // 重置地图尺寸
					this._mapInstance.panTo(new T.LngLat(Number(data.lon), Number(data.lat)), data.zoom || this
						._mapInstance.getZoom());
				} catch (err) {
					console.error(err);
				}
			},
			// 设置地图显示类型
			_setType(data) {
				try {
					this._mapInstance.setMapType(data.type === 1 ? TMAP_SATELLITE_MAP : TMAP_NORMAL_MAP);
				} catch (err) {
					console.error(err);
				}
			},
			// 查看look
			_look() {
				try {
					const zzz = this._mapInstance.getCenter();
					// //创建标注对象
					// var marker = new T.Marker(zzz);
					// //向地图上添加标注
					// this._mapInstance.addOverLay(marker);
					console.log('aaaaaa', resulet);
				} catch (err) {
					console.error(err);
				}
			},
			// 设置地图缩放
			_setZoom(data) {
				try {
					this._mapInstance.setZoom(data.zoom);
				} catch (err) {
					console.error(err);
				}
			},
			// 设置注记
			_setMarkers(data) {
				try {
					// 清空当前所有注记
					if (!this._markerList) this._markerList = [];
					this._markerList.forEach(marker => this._mapInstance.removeOverLay(marker));
					this._markerList = [];
					// 创建新注记
					data.markers && data.markers.forEach(item => {
						const icon = new T.Icon({
							iconUrl: item.icon,
							iconSize: new T.Point(item.width || 24, item.height || 24),
							iconAnchor: new T.Point(item.offsetX || item.width / 2, item.offsetY || item
								.height)
						});
						const marker = new T.Marker(new T.LngLat(item.lon, item.lat), {
							icon: icon
						});
						this._markerList.push(marker);
						this._mapInstance.addOverLay(marker);
					});
				} catch (err) {
					console.error(err);
				}
			},
			// 释放地图
			_dispose() {
				delete this._mapInstance;
				this._mapInstance = null;
				this._unbindEvent();
			}
		},
	};
</script>
 
<style lang="scss" scoped>
	.ly-map-wrapper {
		width: 100%;
		height: 100%;
		position: relative;
		overflow: hidden;
		background: #f0f0f0;
 
		.ly-map {
			width: 100%;
			height: 50%;
		}
 
		// 中心点图标样式 
		.ly-center-icon {
			position: absolute;
			z-index: 401;
			left: 50%;
			top: 25%;
			transform: translateX(-50%) translateY(-100%);
			width: 32px;
			height: 32px;
		}
 
		// 右下角定位图标样式
		.ly-location-icon {
			position: absolute;
			z-index: 401;
			right: 24rpx;
			top: 40%;
			// bottom: 24rpx;
			width: 72rpx;
			height: 72rpx;
			background: #ffffff;
			border-radius: 12rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			box-shadow: 0 0 8rpx rgba(0, 0, 0, .15);
 
			.icon {
				width: 32px;
				height: 32px;
			}
		}
	}
</style>